package com.common.utils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;

public class BeanUtil {

	/**
	 * 下划线 
	 */
	public static final char UNDERLINE = '_';

	public static boolean checkFieldValueNull(Object bean) {
		boolean result = true;
		if (bean == null) {
			return true;
		}
		Class<?> cls = bean.getClass();
		Method[] methods = cls.getDeclaredMethods();
		Field[] fields = cls.getDeclaredFields();
		for (Field field : fields) {
			try {
				String fieldGetName = parGetName(field.getName());
				if (!checkGetMet(methods, fieldGetName)) {
					continue;
				}
				Method fieldGetMet = cls.getMethod(fieldGetName, new Class[] {});
				Object fieldVal = fieldGetMet.invoke(bean, new Object[] {});
				if (fieldVal != null) {
					if ("".equals(fieldVal)) {
						result = true;
					} else {
						result = false;
					}
				}
			} catch (Exception e) {
				continue;
			}
		}
		return result;
	}

	/**
	 * 拼接某属性的 get方法
	 *
	 * @param fieldName
	 * @return String
	 */
	public static String parGetName(String fieldName) {
		if (null == fieldName || "".equals(fieldName)) {
			return null;
		}
		int startIndex = 0;
		if (fieldName.charAt(0) == UNDERLINE) {
			startIndex = 1;
		}
		return "get" + fieldName.substring(startIndex, startIndex + 1).toUpperCase()
				+ fieldName.substring(startIndex + 1);
	}

	/**
	 * 判断是否存在某属性的 get方法
	 *
	 * @param methods
	 * @param fieldGetMet
	 * @return boolean
	 */
	public static boolean checkGetMet(Method[] methods, String fieldGetMet) {
		for (Method met : methods) {
			if (fieldGetMet.equals(met.getName())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 
	 * @Title: isProperty
	 * @Description:  
	 * @param bean         对象
	 * @param propertyName  
	 * @return
	 * @return: boolean 有则反之true 反之false
	 */
	public static boolean isProperty(Object bean, String propertyName) {
		if (bean == null) {
			return false;
		}
		Class<?> cls = bean.getClass();
		PropertyDescriptor[] propertys = org.springframework.beans.BeanUtils.getPropertyDescriptors(cls);
		for (PropertyDescriptor property : propertys) {
			String fieldName = property.getName();
			if (fieldName != null && propertyName != null && fieldName.equals(propertyName)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @description 判断当前对象是否为空
	 * @author jiangwei
	 * @date 2020/9/18 14:40
	 * @param object
	 * @return boolean
	 **/
	public static boolean objCheckIsNull(Object object) {
		return objCheckIsNull(object, null, null);
	}

	/**
	 * @description 判断当前对象是否为空（包括所有属性为空）  
	 * @author  
	 * @date 2020/5/22 10:14
	 * @param object           入参对象
	 * @param excludeNameList   
	 * @param excludeValueList  
	 * @return boolean
	 **/
	public static boolean objCheckIsNull(Object object, List<String> excludeNameList, List<Object> excludeValueList) {

		if (object == null) {
			return true;
		}
		// 得到类对 
		Class clazz = object.getClass();
		// 得到 
		Field[] fields = clazz.getDeclaredFields();
		// 判断入参
		boolean excludeNameListFlag = false;
		if (excludeNameList != null && excludeNameList.size() > 0) {
			excludeNameListFlag = true;
		}
		boolean excludeValueListFlag = false;
		if (excludeValueList != null && excludeValueList.size() > 0) {
			excludeValueListFlag = true;
		}
		// 定义返回结果，默认为true
		boolean flag = true;
		for (Field field : fields) {
			field.setAccessible(true);
			Object fieldValue = null;
			String fieldName = null;
			try {
				// 得到属 
				fieldValue = field.get(object);
				// 得到属 
				Type fieldType = field.getGenericType();
				// 得到属 
				fieldName = field.getName();
				//  
				if (excludeNameListFlag) {
					for (String s : excludeNameList) {
						if (fieldName.equals(s)) {
							fieldValue = null;
						}
					}
				}
				// 剔除指定属
				if (excludeValueListFlag) {
					for (Object obj : excludeValueList) {
						if (fieldValue == obj) {
							fieldValue = null;
						}
					}
				}
			} catch (IllegalArgumentException | IllegalAccessException e) {
				e.printStackTrace();
			}
			// 只要有一个属性不为null 就返回false 表示对象不为null 忽略序列
			if (fieldValue != null && !"serialVersionUID".equals(fieldName)) {
				flag = false;
				break;
			}
		}
		return flag;
	}
}
